package edu.pku.sei.modeler.editpolicies;

import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gef.requests.CreateConnectionRequest;
import org.eclipse.gef.requests.ReconnectRequest;

import edu.pku.sei.modeler.editparts.ExecutionSpecificationEditpart;
import edu.pku.sei.modeler.editparts.InteractionEditpart;
import edu.pku.sei.modeler.editparts.LifelineEditpart;
import edu.pku.sei.modeler.model.structure.MetaLink;
import edu.pku.sei.modeler.model.structure.MetaNode;
import edu.pku.sei.modeler.model.uml.BasicInteractions.Interaction;
import edu.pku.sei.modeler.model.uml.Dependencies.Dependency;
import edu.pku.sei.modeler.model.uml.Kernel.Comment;
import edu.pku.sei.modeler.uml.commands.UMLCommentLinkCreateCommand;
import edu.pku.sei.modeler.uml.commands.UMLConnectionCreateCommand;
import edu.pku.sei.modeler.uml.commands.sequence.SequenceDiagramConnectionCreateFactory;

public class SequenceNodeEditPolicy extends UMLDiagramNodeEditPolicy {

	@Override
	protected Command getConnectionCompleteCommand(
			CreateConnectionRequest request) {
		
		
		UMLConnectionCreateCommand command = (UMLConnectionCreateCommand) request
				.getStartCommand();
		if (command.getSource().getModelElement() instanceof Comment) {
			return SequenceDiagramConnectionCreateFactory.INSTANCE.completeCommand(
					(UMLConnectionCreateCommand) request.getStartCommand(), (MetaNode)getHost().getModel());
		}
		if (!(request.getTargetEditPart() instanceof ExecutionSpecificationEditpart
				|| request.getTargetEditPart() instanceof LifelineEditpart)) {
			return null;
		}
		command.setTarget((MetaNode) getHost().getModel());
		if (getHost() instanceof ExecutionSpecificationEditpart
				&& request.getSourceEditPart() != null) {
			if (request.getSourceEditPart() == request.getTargetEditPart()) {
				MetaLink link = command.getLink();
				MetaNode node = (MetaNode) getHost().getModel();
				ExecutionSpecificationEditpart editpart = (ExecutionSpecificationEditpart)getHost();
				Point pt = request.getLocation().getCopy();
				editpart.getFigure().translateToRelative(pt);
				int msgdelay = pt.y - link.getOffset() - node.getLocationY();
				if (msgdelay < 0) msgdelay = 0;
				link.setDelay(msgdelay);
			} else {
				MetaLink link = command.getLink();
				link.setDelay(0);
			}
		} else if (getHost() instanceof LifelineEditpart
				&& request.getSourceEditPart() != null) {
			if (request.getSourceEditPart() == request.getTargetEditPart()) {
				MetaLink link = command.getLink();
				MetaNode node = (MetaNode) getHost().getModel();
				LifelineEditpart editpart = (LifelineEditpart)getHost();
				Point pt = request.getLocation().getCopy();
				editpart.getFigure().translateToRelative(pt);
				int msgdelay = pt.y - link.getOffset() - node.getLocationY();
				if (msgdelay < 0) msgdelay = 0;
				link.setDelay(msgdelay);
			} else {
				MetaLink link = command.getLink();
				link.setDelay(0);
			}
		}
		
		
		return command;
	}

	@Override
	protected Command getConnectionCreateCommand(CreateConnectionRequest request) {
		MetaLink link = (MetaLink) request.getNewObject();
		MetaNode node = (MetaNode) getHost().getModel();
		// YangYuanzu: set link offset...
		if (getHost() instanceof ExecutionSpecificationEditpart) {
			ExecutionSpecificationEditpart editpart = (ExecutionSpecificationEditpart)getHost();
			Point pt = request.getLocation().getCopy();
			editpart.getFigure().translateToRelative(pt);
			link.setOffset(pt.y - node.getLocationY());
		} else if (getHost() instanceof LifelineEditpart) {
			LifelineEditpart editpart = (LifelineEditpart)getHost();
			Point pt = request.getLocation().getCopy();
			editpart.getFigure().translateToRelative(pt);
			link.setOffset(pt.y - node.getLocationY());
		} 
		
		UMLConnectionCreateCommand command = SequenceDiagramConnectionCreateFactory.INSTANCE
				.createCommand(link, (MetaNode) getHost().getModel());
		request.setStartCommand(command);
		return command;
	}

	@Override
	protected Command getReconnectSourceCommand(ReconnectRequest request) {
		
		if (getHost() == request.getConnectionEditPart().getSource()) {
			MetaLink link = (MetaLink)request.getConnectionEditPart().getModel();
			MetaNode node = (MetaNode) getHost().getModel();
			int newOffset = -1;
			if (getHost() instanceof ExecutionSpecificationEditpart) {
				ExecutionSpecificationEditpart editpart = (ExecutionSpecificationEditpart)getHost();
				Point pt = request.getLocation().getCopy();
				editpart.getFigure().translateToRelative(pt);
				newOffset = pt.y - node.getLocationY();
				return SequenceDiagramConnectionCreateFactory.INSTANCE.createReconnectSourceCommand(
						link, newOffset);
			} else if (getHost() instanceof LifelineEditpart) {
				LifelineEditpart editpart = (LifelineEditpart) getHost();
				Point pt = request.getLocation().getCopy();
				editpart.getFigure().translateToRelative(pt);
				newOffset = pt.y - node.getLocationY();
				return SequenceDiagramConnectionCreateFactory.INSTANCE.createReconnectSourceCommand(
						link, newOffset);
			}
			
		}
		return UnexecutableCommand.INSTANCE;
	}

	@Override
	protected Command getReconnectTargetCommand(ReconnectRequest request) {
		if (getHost() == request.getConnectionEditPart().getTarget()) {
			MetaLink link = (MetaLink)request.getConnectionEditPart().getModel();
			MetaNode node = (MetaNode) request.getConnectionEditPart().getSource().getModel();
			int newOffset = -1;
			int newDelay = -1;
			if (getHost() instanceof ExecutionSpecificationEditpart) {
				ExecutionSpecificationEditpart editpart = 
					(ExecutionSpecificationEditpart)request.getConnectionEditPart().getSource();
				Point pt = request.getLocation().getCopy();
				editpart.getFigure().translateToRelative(pt);
				newOffset = link.getOffset();
				newDelay = pt.y - node.getLocationY() - newOffset;
				if (newDelay < 0) newDelay = 0;
				return SequenceDiagramConnectionCreateFactory.INSTANCE.createReconnectTargetCommand(
						link, newOffset, newDelay);
			} else if (getHost() instanceof LifelineEditpart) {
				LifelineEditpart editpart = (LifelineEditpart) request.getConnectionEditPart().getSource();
				Point pt = request.getLocation().getCopy();
				editpart.getFigure().translateToRelative(pt);
				newOffset = link.getOffset();
				newDelay = pt.y - node.getLocationY() - newOffset;
				if (newDelay < 0) newDelay = 0;
				return SequenceDiagramConnectionCreateFactory.INSTANCE.createReconnectTargetCommand(
						link, newOffset, newDelay);
			}
			
		}
		return UnexecutableCommand.INSTANCE;
	}

}
